﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//https://baike.baidu.com/item/HSV/547122?fr=aladdin
#region ColorUtilities

public static class HSVUtil
{

    public static HsvColor ConvertRgbToHsv(Color color)
    {
        return ConvertRgbToHsv((int)(color.r * 255), (int)(color.g * 255), (int)(color.b * 255));
    }

    //Converts an RGB color to an HSV color.
    public static HsvColor ConvertRgbToHsv(float r, float b, float g)
    {
        float delta, min;
        float h = 0, s, v;

        min = Math.Min(Math.Min(r, g), b);
        v = Math.Max(Math.Max(r, g), b);
        delta = v - min;

        if (v == 0.0)
            s = 0;
        else
            s = delta / v;

        if (s == 0)
            h = 360;
        else
        {
            if (r == v)
                h = (g - b) / delta;
            else if (g == v)
                h = 2 + (b - r) / delta;
            else if (b == v)
                h = 4 + (r - g) / delta;

            h *= 60;
            if (h <= 0.0)
                h += 360;
        }

        HsvColor hsvColor = new HsvColor();
        hsvColor.H = 360 - h;
        hsvColor.S = s;
        hsvColor.V = v / 255;

        return hsvColor;

    }

    // Converts an HSV color to an RGB color.
    public static Color ConvertHsvToRgb(float h /* 0~360 degrees */, float s /* 0 ~ 1.0 */, float v /* 0 ~ 1.0 */ )
    {
        float f, p, q, t;

        if (s == 0)
        { // achromatic (grey)
            return new Color(v, v, v);
        }


        h /= 60;      // sector 0 to 5
        int i = (int)Math.Floor(h);
        f = h - i;      // factorial part of h
        p = v * (1 - s);
        q = v * (1 - s * f);
        t = v * (1 - s * (1 - f));

        switch (i)
        {
            case 0:
                return new Color(v, t, p);
            case 1:
                return new Color(q, v, p);
            case 2:
                return new Color(p, v, t);
            case 3:
                return new Color(p, q, v);
            case 4:
                return new Color(t, p, v);
            case 6:
                return new Color(v, t, p);
            default:
                return new Color(v, p, q);
        }

    }
}


#endregion ColorUtilities


// Describes a color in terms of
// Hue, Saturation, and Value (brightness)
#region HsvColor

public struct HsvColor
{
    /// <summary>
    /// The Hue, ranges between 0 and 360
    /// </summary>
    public float H;

    /// <summary>
    /// The saturation, ranges between 0 and 1
    /// </summary>
    public float S;

    // The value (brightness), ranges between 0 and 1
    public float V;

    public float normalizedH
    {
        get { return (float) H / 360f; }

        set { H = (float) value * 360; }
    }

    public float normalizedS
    {
        get { return (float) S; }
        set { S = (float) value; }
    }

    public float normalizedV
    {
        get { return (float) V; }
        set { V = (float) value; }
    }

    public HsvColor(float h, float s, float v)
    {
        this.H = h;
        this.S = s;
        this.V = v;
    }

    public override string ToString()
    {
        return "{" + H.ToString("f2") + "," + S.ToString("f2") + "," + V.ToString("f2") + "}";
    }
}

#endregion HsvColor